package webx

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"

	"gitee.com/xungen/goweb/errno"
	"gitee.com/xungen/goweb/utils"
)

func init() {
	httpHandle("/cgidoc", cgidoc)
	httpHandle("/getcgilist", getcgilist)
	httpHandle("/getcgidoclist", getcgidoclist)
}

func param(request *http.Request, name string) string {
	return request.FormValue(name)
}

func getCgiEnabled(access string) int {
	switch strings.ToLower(access) {
	case "public":
		return 3
	case "protect":
		return 2
	default:
		return 1
	}
}

func responseJson(out http.ResponseWriter, dest any) {
	if msg, err := json.Marshal(dest); err == nil {
		out.Header().Add("Content-Type", "application/json;charset=utf-8")
		errno.AssertNoError(writeAll(out, msg))
	} else {
		errno.SYSERR.Panic()
	}
}

func cgidoc(response http.ResponseWriter, request *http.Request) {
	padding := param(request, "padding")
	path := param(request, "path")
	doc := getDocument(path)
	rspdoc := doc.response
	reqdoc := doc.request
	remark := doc.remark

	if reqdoc == "" && rspdoc == "" && remark == "" {
		reqdoc = "<td style='color:#B00;height:24px'>没有参数或没有编写文档</td><td></td><td></td><td></td>"
		rspdoc = reqdoc
	}

	if padding == "" {
		padding = "2vh 20vw"
	}

	path = strings.Trim(path, "/")
	path = strings.ReplaceAll(path, "/", ".")
	reqdoc = strings.ReplaceAll(reqdoc, "<td>required</td>", "<td>必填</td>")
	rspdoc = strings.ReplaceAll(rspdoc, "<td>required</td>", "<td>必填</td>")
	reqdoc = strings.ReplaceAll(reqdoc, "<td>optional</td>", "<td>可选</td>")
	rspdoc = strings.ReplaceAll(rspdoc, "<td>optional</td>", "<td>可选</td>")

	temp := getCgidocTemplate()
	temp = strings.ReplaceAll(temp, "<%=path%>", path)
	temp = strings.ReplaceAll(temp, "<%=remark%>", remark)
	temp = strings.ReplaceAll(temp, "<%=reqdoc%>", reqdoc)
	temp = strings.ReplaceAll(temp, "<%=rspdoc%>", rspdoc)
	temp = strings.ReplaceAll(temp, "<%=padding%>", padding)

	response.Header().Add("Content-Type", "text/html;charset=utf-8")
	errno.AssertNoError(writeAll(response, []byte(temp)))
}

func getcgilist(response http.ResponseWriter, request *http.Request) {
	type Item struct {
		Path    string `json:"path"`
		Remark  string `json:"remark"`
		Enabled int    `json:"enabled"`
	}

	type Response struct {
		Code int    `json:"code"`
		List []Item `json:"list"`
	}

	num := 0
	path := param(request, "path")
	access := errno.IgnoreError(utils.ToInteger[int](param(request, "access")))
	system := errno.IgnoreError(utils.ToInteger[int](param(request, "system")))
	enabled := errno.IgnoreError(utils.ToInteger[int](param(request, "enabled")))

	list := getDocumentList()
	res := Response{Code: len(list), List: make([]Item, len(list))}
	for _, doc := range list {
		var key = doc.path[1:]
		if system <= 0 {
			if key == "execmodule" {
				continue
			}
		}

		var item Item
		item.Path = key
		item.Remark = doc.remark
		item.Enabled = getCgiEnabled(doc.access)

		if path == "" || strings.Contains(item.Path, path) {
			if access > 0 {
				if access <= item.Enabled {
					res.List[num] = item
					num++
				}
			} else {
				if enabled < 0 || enabled == item.Enabled {
					res.List[num] = item
					num++
				}
			}
		}
	}
	res.List = res.List[:num]
	responseJson(response, res)
}

func getcgidoclist(response http.ResponseWriter, request *http.Request) {
	type Item struct {
		Url     string `json:"url"`
		Title   string `json:"title"`
		Folder  string `json:"folder"`
		Remark  string `json:"remark"`
		Enabled int    `json:"enabled"`
	}

	type Response struct {
		Code int    `json:"code"`
		List []Item `json:"list"`
	}

	list := getDocumentList()
	cfg := GetConfig()
	res := Response{Code: len(list), List: make([]Item, len(list))}
	for i, doc := range list {
		item := Item{}
		item.Url = fmt.Sprintf("/cgidoc?padding=0px&path=%s", doc.path)
		item.Title = doc.path[1:]
		item.Folder = cfg.App.Name
		item.Remark = doc.remark
		item.Enabled = getCgiEnabled(doc.access)
		res.List[i] = item
	}
	responseJson(response, res)
}

func getCgidocTemplate() string {
	return `
<!DOCTYPE HTML>
<html>
<head>
<title>接口文档</title>
<meta name='referrer' content='always'/>
<meta http-equiv='x-ua-compatible' content='ie=edge,chrome=1'/>
<meta http-equiv='content-type' content='text/html; charset=utf-8'/>
<meta name='viewport' content='width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'/>
<style>
.CgiDocDiv{
	width: 100%;
	font-size: 13px;
	padding: <%=padding%>;
	display: inline-block;
	box-sizing: border-box;
	font-family: '宋体', 'Helvetica', 'Tahoma', 'Verdana', 'Courier New';
}
.CgiDocHeadDiv{
	width: 100%;
	padding: 4px;
	display: inline-block;
	box-sizing: border-box;
	border-bottom: 1px solid #AAA;
}
.CgiDocPathDiv{
	color: #B00;
	font-size: 2.4rem;
	letter-spacing: -1px;
	display: inline-block;
}
.CgiDocRemarkDiv{
	color: #456;
	font-size: 1.8rem;
	font-weight: bold;
	padding-left: 8px;
	letter-spacing: -1px;
	display: inline-block;
}
.CgiDocParamDiv{
	padding: 4px;
	margin-top: 24px;
	font-weight: bold;
	font-size: 1.4rem;
}
.CgiDocListTable{
	width: 100%;
	background: #FFF;
	border-radius: 4px;
	border-collapse: collapse;
}
.CgiDocListTable span{
	color: #098;
	padding-right: 4px;
}
.CgiDocListTable td{
	padding: 2px 8px;
	line-height: 18px;
}
.CgiDocListTable tr:first-child{
	background: #888;
	font-weight: bold;
	font-size: 0.95rem;
}
.CgiDocListTable tr td:nth-child(1){
	min-width: 15vw;
}
.CgiDocListTable tr td:nth-child(2){
	min-width: 5vw;
}
.CgiDocListTable tr td:nth-child(3){
	min-width: 5vw;
}
.CgiDocListTable tr td:nth-child(4){
	min-width: 25vw;
}
</style>
</head>

<body>
	<div class='CgiDocDiv'>
		<div class='CgiDocHeadDiv'>
			<div class='CgiDocPathDiv'><%=path%></div>
			<div class='CgiDocRemarkDiv'><%=remark%></div>
		</div>

		<div class='CgiDocParamDiv'>请求参数</div>
		<table class='CgiDocListTable'>
				<tr><td>字段</td><td>类型</td><td>属性</td><td>说明</td></tr>
				<%=reqdoc%>
		</table>

		<div class='CgiDocParamDiv'>应答参数</div>
		<table class='CgiDocListTable'>
				<tr><td>字段</td><td>类型</td><td>属性</td><td>说明</td></tr>
				<%=rspdoc%>
		</table>
	</div>
</body>
</html>
`
}
